﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        // 常量定义
        private const int GRID_SIZE = 20;
        private const int MODULE_PADDING = 90;//模块左顶点位置
        private const int Module_Y_moves_up = 70;//模块左顶点位置
        private const int LIBRARY_TITLE_HEIGHT = 150;
        private const int CONNECTION_POINT_SIZE = 15;
        private const int CORNER_RADIUS = 10; // 增大圆角半径
        private const int MODULE_SPACING = 100;
        private const int LIBRARY_BORDER_RADIUS = 12;
        private const int SHADOW_OFFSET = 3; // 阴影偏移量
        private const int SHADOW_BLUR = 8;   // 阴影模糊度

        // 优化后的颜色方案 - 更现代的配色
        private static readonly Color LibraryTitleColor = Color.FromArgb(52, 73, 94);
        private static readonly Color LibraryTitleTextColor = Color.White;
        private static readonly Color LibraryItemHoverColor = Color.FromArgb(236, 240, 241);
        private static readonly Color ConnectionLineColor = Color.FromArgb(52, 152, 219);
        private static readonly Color GridColor = Color.FromArgb(245, 245, 245);
        private static readonly Color ShadowColor = Color.FromArgb(100, 0, 0, 0); // 阴影颜色
        private static readonly Color SelectedBorderColor = Color.FromArgb(52, 152, 219);

        // 枚举和类定义--------------------
        public enum ModuleType { Start, Input, Output, Acquire_Image, Grayscale_conversion, Color_recognition, Edge_Search, Calculation_results, Display_image }

        public enum ConnectionPointType { Input, Output }

        public class Module
        {
            public string Name { get; set; }
            public ModuleType Type { get; set; }
            public Point Location { get; set; }
            public Size Size { get; set; }
            public List<ConnectionPoint> ConnectionPoints { get; set; }
            public bool IsSelected { get; set; }
            public bool IsPrototype { get; set; }
            public bool IsHovered { get; set; } // 新增悬停状态

            public Module(string name, ModuleType type, Point location, bool isPrototype = false)
            {
                Name = name;
                Type = type;
                Location = location;
                Size = new Size(160, 80);
                ConnectionPoints = new List<ConnectionPoint>();
                IsSelected = false;
                IsPrototype = isPrototype;
                IsHovered = false;

                InitializeConnectionPoints();
            }

            // 设置模块的输入属性------------------------------------------------------------------
            private void InitializeConnectionPoints()
            {
                switch (Type)
                {
                    case ModuleType.Start://程序开始
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 1));
                        break;
                    case ModuleType.Input://信号输入
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 1));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Input, 1));
                        break;
                    case ModuleType.Output://信号输出
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Input, 1));
                        break;
                    case ModuleType.Acquire_Image://采集图像
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Input, 1, "触发信号"));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 1, "图像"));
                        break;
                    case ModuleType.Grayscale_conversion://灰度转换
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Input, 1));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 1, "图像"));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 2, "结果"));
                        break;
                    case ModuleType.Color_recognition://颜色识别
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Input, 1));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 1, "图像"));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 2, "结果"));
                        break;
                    case ModuleType.Edge_Search://边缘查找
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Input, 1));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 1, "图像"));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 2, "结果"));
                        break;
                    case ModuleType.Calculation_results://计算结果
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Input, 1, "数据输入"));
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Output, 1, "结果输出"));
                        break;
                    case ModuleType.Display_image://显示图像
                        ConnectionPoints.Add(new ConnectionPoint(this, ConnectionPointType.Input, 1, "图像输入"));
                        break;
                }
            }

            public void Draw(Graphics g, Form1 parentForm)
            {
                // 绘制阴影
                if (!IsPrototype)
                {
                    using (Brush shadowBrush = new SolidBrush(Color.FromArgb(IsSelected ? 120 : 80, 0, 0, 0)))
                    {
                        Rectangle shadowRect = new Rectangle(
                            Location.X + SHADOW_OFFSET,
                            Location.Y + SHADOW_OFFSET,
                            Size.Width,
                            Size.Height);
                        GraphicsPath shadowPath = parentForm.CreateRoundedRectanglePath(shadowRect, CORNER_RADIUS);
                        g.SmoothingMode = SmoothingMode.AntiAlias;
                        g.FillPath(shadowBrush, shadowPath);
                    }
                }

                // 模块主体路径
                Rectangle mainRect = new Rectangle(Location.X, Location.Y, Size.Width, Size.Height);
                GraphicsPath path = parentForm.CreateRoundedRectanglePath(mainRect, CORNER_RADIUS);

                // 模块背景色（根据状态变化）
                Color baseColor;
                switch (Type)
                {
                    case ModuleType.Start:
                        baseColor = Color.FromArgb(240, 128, 128);
                        break;
                    case ModuleType.Input:
                        baseColor = Color.FromArgb(135, 206, 250);
                        break;
                    case ModuleType.Output:
                        baseColor = Color.FromArgb(119, 136, 153);
                        break;
                    case ModuleType.Acquire_Image:
                        baseColor = Color.FromArgb(132, 112, 255);
                        break;
                    case ModuleType.Color_recognition:
                        baseColor = Color.FromArgb(50, 255, 50);
                        break;
                    case ModuleType.Grayscale_conversion:
                        baseColor = Color.FromArgb(255, 165, 0);
                        break;
                    case ModuleType.Edge_Search:
                        baseColor = Color.FromArgb(245, 222, 174);
                        break;
                    case ModuleType.Calculation_results:
                        baseColor = Color.FromArgb(216, 191, 216);
                        break;
                    case ModuleType.Display_image:
                        baseColor = Color.FromArgb(240, 255, 240);
                        break;
                    default:
                        baseColor = Color.LightGray;
                        break;
                }

                // 处理悬停和选中状态的颜色变化
                Color bgColor = IsSelected
                    ? Color.FromArgb(255, Math.Min(baseColor.R + 10, 255), Math.Min(baseColor.G + 10, 255), Math.Min(baseColor.B + 10, 255))
                    : IsHovered
                        ? Color.FromArgb(255, Math.Min(baseColor.R + 5, 255), Math.Min(baseColor.G + 5, 255), Math.Min(baseColor.B + 5, 255))
                        : baseColor;

                // 绘制主体
                using (LinearGradientBrush bgBrush = new LinearGradientBrush(
                    mainRect,
                    Color.FromArgb(255, bgColor.R, bgColor.G, bgColor.B),
                    Color.FromArgb(255, Math.Max(bgColor.R - 10, 0), Math.Max(bgColor.G - 10, 0), Math.Max(bgColor.B - 10, 0)),
                    LinearGradientMode.Vertical))
                using (Pen borderPen = new Pen(IsSelected ? SelectedBorderColor : Color.FromArgb(200, 200, 200), IsSelected ? 2.5f : 1.5f))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.FillPath(bgBrush, path);
                    g.DrawPath(borderPen, path);
                }

                // 绘制模块名称
                using (Font titleFont = new Font("Segoe UI", 11, FontStyle.Bold))
                using (Brush textBrush = new SolidBrush(Color.FromArgb(52, 73, 94)))
                {
                    StringFormat format = new StringFormat
                    {
                        Alignment = StringAlignment.Center,
                        LineAlignment = StringAlignment.Center
                    };
                    g.DrawString(Name, titleFont, textBrush, mainRect, format);
                }

                // 绘制模块类型标签（小字体）
                using (Font typeFont = new Font("Segoe UI", 8, FontStyle.Regular))
                using (Brush typeBrush = new SolidBrush(Color.FromArgb(255, 255, 255)))
                {
                    string typeName = Type.ToString();
                    SizeF textSize = g.MeasureString(typeName, typeFont);
                    g.DrawString(typeName, typeFont, typeBrush,
                        Location.X + 8,
                        Location.Y + 5);
                }

                // 绘制连接点
                foreach (var point in ConnectionPoints)
                    point.Draw(g);
            }
        }

        public class ConnectionPoint
        {
            public Module ParentModule { get; set; }
            public ConnectionPointType Type { get; set; }
            public int Index { get; set; }
            public string Label { get; set; }
            public Point Location { get; set; }
            public bool IsConnected { get; set; }
            public List<Connection> Connections { get; set; }
            public bool IsHovered { get; set; }

            public ConnectionPoint(Module parent, ConnectionPointType type, int index, string label = null)
            {
                ParentModule = parent;
                Type = type;
                Index = index;
                Label = label;
                IsConnected = false;
                Connections = new List<Connection>();
                IsHovered = false;
                UpdateLocation();
            }

            public void UpdateLocation()
            {
                if (Type == ConnectionPointType.Input)
                {
                    int inputCount = ParentModule.ConnectionPoints.Count(p => p.Type == ConnectionPointType.Input);
                    int inputIndex = ParentModule.ConnectionPoints.Where(p => p.Type == ConnectionPointType.Input).ToList().IndexOf(this);
                    int y = ParentModule.Location.Y + ParentModule.Size.Height / (inputCount + 1) * (inputIndex + 1);
                    int x = ParentModule.Location.X - CONNECTION_POINT_SIZE / 2;
                    Location = new Point(x, y);
                }
                else
                {
                    int outputCount = ParentModule.ConnectionPoints.Count(p => p.Type == ConnectionPointType.Output);
                    int outputIndex = ParentModule.ConnectionPoints.Where(p => p.Type == ConnectionPointType.Output).ToList().IndexOf(this);
                    int y = ParentModule.Location.Y + ParentModule.Size.Height / (outputCount + 1) * (outputIndex + 1);
                    int x = ParentModule.Location.X + ParentModule.Size.Width + CONNECTION_POINT_SIZE / 2;
                    Location = new Point(x, y);
                }
            }

            public void Draw(Graphics g)
            {
                UpdateLocation();

                // 连接点大小（悬停时放大）
                int size = IsHovered ? CONNECTION_POINT_SIZE + 4 : CONNECTION_POINT_SIZE;

                // 连接点颜色
                Color fillColor = IsHovered
                    ? Color.FromArgb(52, 152, 219)
                    : IsConnected
                        ? Color.FromArgb(46, 204, 113)
                        : Color.FromArgb(189, 195, 199);

                // 绘制连接点
                using (Brush bgBrush = new SolidBrush(fillColor))
                using (Pen borderPen = new Pen(Color.FromArgb(108, 122, 137), 1.2f))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.FillEllipse(bgBrush,
                        Location.X - size / 2,
                        Location.Y - size / 2,
                        size,
                        size);
                    g.DrawEllipse(borderPen,
                        Location.X - size / 2,
                        Location.Y - size / 2,
                        size,
                        size);
                }

                // 绘制方向指示器
                using (Pen arrowPen = new Pen(Color.FromArgb(108, 122, 137), 1.5f))
                {
                    if (Type == ConnectionPointType.Input)
                    {
                        g.DrawLine(arrowPen, Location.X - 5, Location.Y, Location.X + 3, Location.Y);
                        g.DrawLine(arrowPen, Location.X - 1, Location.Y - 3, Location.X + 3, Location.Y);
                        g.DrawLine(arrowPen, Location.X - 1, Location.Y + 3, Location.X + 3, Location.Y);
                    }
                    else
                    {
                        g.DrawLine(arrowPen, Location.X - 3, Location.Y, Location.X + 5, Location.Y);
                        g.DrawLine(arrowPen, Location.X + 1, Location.Y - 3, Location.X - 3, Location.Y);
                        g.DrawLine(arrowPen, Location.X + 1, Location.Y + 3, Location.X - 3, Location.Y);
                    }
                }

                // 绘制标签
                if (!string.IsNullOrEmpty(Label))
                {
                    using (Font labelFont = new Font("Segoe UI", 8, FontStyle.Regular))
                    using (Brush labelBrush = new SolidBrush(Color.FromArgb(108, 122, 137)))
                    {
                        StringFormat format = new StringFormat
                        {
                            Alignment = Type == ConnectionPointType.Input ? StringAlignment.Far : StringAlignment.Near,
                            LineAlignment = StringAlignment.Center
                        };

                        RectangleF labelRect = new RectangleF(
                            Type == ConnectionPointType.Input
                                ? Location.X - size / 2 - 5 - g.MeasureString(Label, labelFont).Width
                                : Location.X + size / 2 + 5,
                            Location.Y - 10,
                            80, 23);//25控制输入输出标签上下位置

                        g.DrawString(Label, labelFont, labelBrush, labelRect, format);
                    }
                }
            }

            public bool ContainsPoint(Point point)
            {
                int size = IsHovered ? CONNECTION_POINT_SIZE + 4 : CONNECTION_POINT_SIZE;
                return new Rectangle(
                    Location.X - size / 2,
                    Location.Y - size / 2,
                    size,
                    size).Contains(point);
            }
        }

        public class Connection
        {
            public ConnectionPoint SourcePoint { get; set; }
            public ConnectionPoint TargetPoint { get; set; }
            public bool IsTemporary { get; set; }
            private Point? customEndPoint = null;
            public bool IsHovered { get; set; } // 新增悬停状态

            public Connection(ConnectionPoint source, ConnectionPoint target, bool isTemporary = false)
            {
                SourcePoint = source;
                TargetPoint = target;
                IsTemporary = isTemporary;
                IsHovered = false;

                if (!isTemporary && source != null && target != null)
                {
                    source.Connections.Add(this);
                    target.Connections.Add(this);
                    source.IsConnected = true;
                    target.IsConnected = true;
                }
            }

            public void SetCustomEndPoint(Point endPoint)
            {
                customEndPoint = endPoint;
            }

            public void Draw(Graphics g)
            {
                if (SourcePoint == null)
                    return;

                Point start = SourcePoint.Location;
                Point end = customEndPoint ?? TargetPoint?.Location ?? start;

                // 优化贝塞尔曲线控制点，使线条更自然
                int controlOffsetX = Math.Max(80, Math.Abs(end.X - start.X) / 2);
                Point control1 = new Point(start.X + (end.X > start.X ? controlOffsetX : -controlOffsetX), start.Y);
                Point control2 = new Point(end.X - (end.X > start.X ? controlOffsetX : -controlOffsetX), end.Y);

                // 线条样式（悬停时加粗）
                using (Pen linePen = new Pen(
                    IsTemporary ? Color.FromArgb(150, 150, 150) :
                    IsHovered ? Color.FromArgb(41, 128, 185) : ConnectionLineColor,
                    IsHovered ? 3f : 2f))
                {
                    linePen.StartCap = LineCap.Round;
                    linePen.EndCap = LineCap.Round;
                    linePen.DashCap = DashCap.Round;

                    // 临时连接线使用虚线
                    if (IsTemporary)
                    {
                        linePen.DashPattern = new float[] { 5, 3 };
                    }

                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.DrawBezier(linePen, start, control1, control2, end);
                }

                // 绘制箭头
                if ((!IsTemporary && TargetPoint != null) || IsTemporary)
                {
                    DrawArrow(g, end, control2);
                }
            }

            private void DrawArrow(Graphics g, Point endPoint, Point controlPoint)
            {
                float dx = endPoint.X - controlPoint.X;
                float dy = endPoint.Y - controlPoint.Y;
                float length = (float)Math.Sqrt(dx * dx + dy * dy);

                if (length == 0) return;

                dx /= length;
                dy /= length;
                const int arrowSize = 10;

                Point arrowPoint1 = new Point(
                    endPoint.X - (int)(dx * arrowSize + dy * arrowSize * 0.7f),
                    endPoint.Y - (int)(dy * arrowSize - dx * arrowSize * 0.7f));

                Point arrowPoint2 = new Point(
                    endPoint.X - (int)(dx * arrowSize - dy * arrowSize * 0.7f),
                    endPoint.Y - (int)(dy * arrowSize + dx * arrowSize * 0.7f));

                using (Pen arrowPen = new Pen(
                    IsTemporary ? Color.FromArgb(150, 150, 150) :
                    IsHovered ? Color.FromArgb(41, 128, 185) : ConnectionLineColor,
                    IsHovered ? 3f : 2f))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.DrawLine(arrowPen, endPoint, arrowPoint1);
                    g.DrawLine(arrowPen, endPoint, arrowPoint2);
                }
            }

            // 检查点是否在线附近（用于悬停检测）
            public bool IsNearPoint(Point point, float threshold = 8f)
            {
                if (SourcePoint == null) return false;

                Point start = SourcePoint.Location;
                Point end = customEndPoint ?? TargetPoint?.Location ?? start;

                int controlOffsetX = Math.Max(80, Math.Abs(end.X - start.X) / 2);
                Point control1 = new Point(start.X + (end.X > start.X ? controlOffsetX : -controlOffsetX), start.Y);
                Point control2 = new Point(end.X - (end.X > start.X ? controlOffsetX : -controlOffsetX), end.Y);

                // 采样贝塞尔曲线上的点进行距离检测
                for (float t = 0; t <= 1; t += 0.05f)
                {
                    float x = (float)(Math.Pow(1 - t, 3) * start.X +
                                     3 * Math.Pow(1 - t, 2) * t * control1.X +
                                     3 * (1 - t) * Math.Pow(t, 2) * control2.X +
                                     Math.Pow(t, 3) * end.X);

                    float y = (float)(Math.Pow(1 - t, 3) * start.Y +
                                     3 * Math.Pow(1 - t, 2) * t * control1.Y +
                                     3 * (1 - t) * Math.Pow(t, 2) * control2.Y +
                                     Math.Pow(t, 3) * end.Y);

                    float distance = (float)Math.Sqrt(Math.Pow(x - point.X, 2) + Math.Pow(y - point.Y, 2));
                    if (distance < threshold)
                        return true;
                }
                return false;
            }
        }

        // 窗体相关逻辑
        private Panel moduleLibraryPanel;
        private Panel workspacePanel;
        private List<Module> modules;
        private List<Connection> connections;
        private Connection tempConnection;
        private ConnectionPoint selectedConnectionPoint;
        private List<Module> modulePrototypes;
        private Module draggingModule;
        private Point dragOffset;
        private int? hoveredPrototypeIndex = null;
        private Connection hoveredConnection = null;

        public Form1()
        {
            InitializeUI();
        }

        //UI初始化
        private void InitializeUI()
        {
            Text = "流程图设计工具";
            Size = new Size(1900, 1020);
            StartPosition = FormStartPosition.CenterScreen;
            BackColor = Color.FromArgb(248, 249, 250);
            //------------------------------------------------------------------------------
            // 模块库面板
            moduleLibraryPanel = new Panel
            {
                Dock = DockStyle.Left,
                Width = 350,
                BackColor = Color.White,
                BorderStyle = BorderStyle.None
            };
            Controls.Add(moduleLibraryPanel);

            // 工作区面板
            workspacePanel = new Panel
            {
                Dock = DockStyle.Fill,
                BackColor = Color.White
            };
            Controls.Add(workspacePanel);

            // 启用双缓冲防止闪烁
            typeof(Panel).InvokeMember("DoubleBuffered",
                BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                null, workspacePanel, new object[] { true });
            typeof(Panel).InvokeMember("DoubleBuffered",
                BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                null, moduleLibraryPanel, new object[] { true });

            // 初始化集合
            modules = new List<Module>();
            connections = new List<Connection>();

            // 模块原型
            //---------------------------------------------------------------------------------
            //new Point(MODULE_PADDING, LIBRARY_TITLE_HEIGHT + MODULE_PADDING), true)工具箱Y轴间隔
            modulePrototypes = new List<Module>
            {
                new Module("程序开始",  ModuleType.Start,      new Point(MODULE_PADDING, LIBRARY_TITLE_HEIGHT + MODULE_PADDING-Module_Y_moves_up), true),
                new Module("采集图像",  ModuleType.Acquire_Image,    new Point(MODULE_PADDING, LIBRARY_TITLE_HEIGHT + MODULE_PADDING + MODULE_SPACING-Module_Y_moves_up), true),
                new Module("灰度转换",  ModuleType.Grayscale_conversion,     new Point(MODULE_PADDING, (LIBRARY_TITLE_HEIGHT + MODULE_PADDING + MODULE_SPACING * 2)-Module_Y_moves_up), true),
                new Module("颜色识别",  ModuleType.Color_recognition,   new Point(MODULE_PADDING, (LIBRARY_TITLE_HEIGHT + MODULE_PADDING + MODULE_SPACING * 3)-Module_Y_moves_up), true),
                new Module("边缘查找",  ModuleType.Edge_Search,   new Point(MODULE_PADDING, (LIBRARY_TITLE_HEIGHT + MODULE_PADDING + MODULE_SPACING * 4)-Module_Y_moves_up), true),
                new Module("计算结果",  ModuleType.Calculation_results,   new Point(MODULE_PADDING, (LIBRARY_TITLE_HEIGHT + MODULE_PADDING + MODULE_SPACING * 5)-Module_Y_moves_up), true),
                new Module("信号输出",  ModuleType.Output,   new Point(MODULE_PADDING, (LIBRARY_TITLE_HEIGHT + MODULE_PADDING + MODULE_SPACING * 6)-Module_Y_moves_up), true),
                new Module("显示图像",  ModuleType.Display_image,   new Point(MODULE_PADDING, (LIBRARY_TITLE_HEIGHT + MODULE_PADDING + MODULE_SPACING * 7)-Module_Y_moves_up), true)
            };

            // 事件绑定
            workspacePanel.Paint += WorkspacePanel_Paint;
            workspacePanel.MouseDown += WorkspacePanel_MouseDown;
            workspacePanel.MouseMove += WorkspacePanel_MouseMove;
            workspacePanel.MouseUp += WorkspacePanel_MouseUp;
            workspacePanel.MouseLeave += WorkspacePanel_MouseLeave;
            workspacePanel.MouseClick += WorkspacePanel_MouseClick;
            //workspacePanel.MouseRightButtonDown += WorkspacePanel_MouseRightButtonDown; // 添加右键事件
            workspacePanel.MouseDown += WorkspacePanel_MouseDown; // 确保MouseDown事件已绑定

            moduleLibraryPanel.Paint += ModuleLibraryPanel_Paint;
            moduleLibraryPanel.MouseDown += ModuleLibraryPanel_MouseDown;
            moduleLibraryPanel.MouseMove += ModuleLibraryPanel_MouseMove;
            moduleLibraryPanel.MouseUp += ModuleLibraryPanel_MouseUp;
            moduleLibraryPanel.MouseLeave += ModuleLibraryPanel_MouseLeave;

            // 模块库边框绘制
            moduleLibraryPanel.Paint += (sender, e) =>
            {
                using (Pen borderPen = new Pen(Color.FromArgb(221, 221, 221), 1f))
                using (Brush shadowBrush = new SolidBrush(Color.FromArgb(50, 0, 0, 0)))
                {
                    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

                    // 绘制阴影
                    Rectangle shadowRect = new Rectangle(
                        0, 0, moduleLibraryPanel.Width, moduleLibraryPanel.Height);
                    GraphicsPath shadowPath = CreateRoundedRectanglePath(shadowRect, LIBRARY_BORDER_RADIUS);
                    e.Graphics.FillPath(shadowBrush, shadowPath);

                    // 绘制边框
                    Rectangle rect = new Rectangle(0, 0, moduleLibraryPanel.Width - 1, moduleLibraryPanel.Height - 1);
                    GraphicsPath path = CreateRoundedRectanglePath(rect, LIBRARY_BORDER_RADIUS);
                    e.Graphics.DrawPath(borderPen, path);
                }
            };
        }

        // 添加右键点击事件处理
        private void WorkspacePanel_MouseRightButtonDown(object sender, MouseEventArgs e)
        {
            // 查找鼠标位置下的模块
            Module clickedModule = FindModuleAt(e.Location);

            // 如果点击了已选中的模块，则删除它
            if (clickedModule != null && clickedModule.IsSelected)
            {
                RemoveModule(clickedModule);
            }
        }

        // 删除模块及其相关连接
        private void RemoveModule(Module module)
        {
            // 先删除与该模块相关的所有连接
            var connectionsToRemove = new List<Connection>();

            foreach (var connection in connections)
            {
                if (connection.SourcePoint?.ParentModule == module ||
                    connection.TargetPoint?.ParentModule == module)
                {
                    connectionsToRemove.Add(connection);
                }
            }

            foreach (var connection in connectionsToRemove)
            {
                RemoveConnection(connection);
            }

            // 然后从模块列表中移除该模块
            modules.Remove(module);
            workspacePanel.Invalidate();
        }

        private void ModuleLibraryPanel_Paint(object sender, PaintEventArgs e)
        {
            // 绘制标题区域渐变背景
            using (LinearGradientBrush titleBrush = new LinearGradientBrush(
                new Point(0, 0),
                new Point(0, LIBRARY_TITLE_HEIGHT),
                LibraryTitleColor,
                Color.FromArgb(41, 58, 74)))
            {
                GraphicsPath titlePath = CreateRoundedRectanglePath(
                    new Rectangle(0, 0, moduleLibraryPanel.Width, LIBRARY_TITLE_HEIGHT),
                    LIBRARY_BORDER_RADIUS);
                e.Graphics.FillPath(titleBrush, titlePath);
            }

            // 绘制标题文本
            using (Font titleFont = new Font("Segoe UI", 16, FontStyle.Bold))
            using (Brush textBrush = new SolidBrush(LibraryTitleTextColor))
            using (Font subtitleFont = new Font("Segoe UI", 9, FontStyle.Regular))
            {
                e.Graphics.DrawString("工具模块库", titleFont, textBrush,
                    new RectangleF(MODULE_PADDING, 20, moduleLibraryPanel.Width - 40, 50)); //50是文本显示区域大小，20是Y轴位置

                e.Graphics.DrawString("拖拽模块到工作区开始设计", subtitleFont,
                    new SolidBrush(Color.FromArgb(220, 220, 220)),
                    new RectangleF(MODULE_PADDING - 27, 90, moduleLibraryPanel.Width - 40, 50));
            }

            // 绘制分隔线
            using (Pen linePen = new Pen(Color.FromArgb(221, 221, 221), 1f))
            {
                e.Graphics.DrawLine(linePen,
                    MODULE_PADDING, LIBRARY_TITLE_HEIGHT,
                    moduleLibraryPanel.Width - MODULE_PADDING, LIBRARY_TITLE_HEIGHT);
            }

            // 绘制模块原型
            for (int i = 0; i < modulePrototypes.Count; i++)
            {
                var prototype = modulePrototypes[i];
                bool isHovered = hoveredPrototypeIndex.HasValue && hoveredPrototypeIndex.Value == i;

                // 原型背景（悬停效果）
                Color bgColor = isHovered ? LibraryItemHoverColor : Color.White;
                using (Brush bgBrush = new SolidBrush(bgColor))
                using (Pen borderPen = new Pen(isHovered ? Color.FromArgb(180, 180, 180) : Color.Transparent, 1f))
                {
                    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                    Rectangle rect = new Rectangle(
                        prototype.Location.X - 10,
                        prototype.Location.Y - 10,
                        prototype.Size.Width + 20,
                        prototype.Size.Height + 20);
                    GraphicsPath path = CreateRoundedRectanglePath(rect, 10);
                    e.Graphics.FillPath(bgBrush, path);
                    e.Graphics.DrawPath(borderPen, path);
                }

                prototype.Draw(e.Graphics, this);
            }
        }

        private void WorkspacePanel_Paint(object sender, PaintEventArgs e)
        {
            // 绘制网格背景（更淡的网格）
            DrawGridBackground(e.Graphics);

            // 绘制连接线（先绘制连接线，避免被模块遮挡）
            foreach (var connection in connections)
                connection.Draw(e.Graphics);

            // 绘制临时连接线
            if (tempConnection != null)
                tempConnection.Draw(e.Graphics);

            // 绘制模块（后绘制模块，覆盖连接线）
            foreach (var module in modules)
                module.Draw(e.Graphics, this);
        }

        private void DrawGridBackground(Graphics g)
        {
            // 绘制浅色背景
            g.FillRectangle(Brushes.White, workspacePanel.ClientRectangle);

            // 绘制网格线
            using (Pen gridPen = new Pen(GridColor, 1))
            {
                int gridOffsetX = 0;
                int gridOffsetY = 0;

                // 横向网格线
                for (int y = gridOffsetY; y < workspacePanel.Height; y += GRID_SIZE)
                    g.DrawLine(gridPen, 0, y, workspacePanel.Width, y);

                // 纵向网格线
                for (int x = gridOffsetX; x < workspacePanel.Width; x += GRID_SIZE)
                    g.DrawLine(gridPen, x, 0, x, workspacePanel.Height);
            }
        }

        //右击处理
        private void WorkspacePanel_MouseDown(object sender, MouseEventArgs e)
        {
            // 在方法开始处声明变量
            Module clickedModule = null;
            ConnectionPoint clickedPoint = null;

            // 清除所有选中状态，除了右键点击可能保留的选中模块
            if (e.Button != MouseButtons.Right)
            {
                foreach (var module in modules)
                    module.IsSelected = false;
            }

            // 右键点击处理
            if (e.Button == MouseButtons.Right)
            {
                // 1. 检查是否点击了模块
                clickedModule = FindModuleAt(e.Location);

                // 如果点击了已选中的模块，则删除它
                if (clickedModule != null && clickedModule.IsSelected)
                {
                    RemoveModule(clickedModule);
                    return;
                }

                // 2. 检查是否点击了连接线
                CheckConnectionHover(e.Location);
                if (hoveredConnection != null)
                {
                    // 右键删除连接线
                    RemoveConnection(hoveredConnection);
                    return;
                }

                // 3. 右键点击空白处清除选中状态
                if (clickedModule == null)
                {
                    foreach (var module in modules)
                        module.IsSelected = false;
                    workspacePanel.Invalidate();
                    return;
                }
                else
                {
                    // 如果点击了未选中的模块，选中它
                    clickedModule.IsSelected = true;
                    workspacePanel.Invalidate();
                }
            }

            // 左键点击处理
            else if (e.Button == MouseButtons.Left)
            {
                // 检查是否点击了连接点
                clickedPoint = FindConnectionPointAt(e.Location);
                if (clickedPoint != null)
                {
                    selectedConnectionPoint = clickedPoint;
                    tempConnection = new Connection(clickedPoint, null, true);
                    tempConnection.SetCustomEndPoint(clickedPoint.Location);
                    workspacePanel.Invalidate();
                    return;
                }

                // 检查是否点击了模块
                clickedModule = FindModuleAt(e.Location);
                if (clickedModule != null)
                {
                    clickedModule.IsSelected = true;

                    // 如果不是点击连接点，则开始拖拽
                    if (!IsPointOnConnectionPoint(e.Location, clickedModule))
                    {
                        draggingModule = clickedModule;
                        dragOffset = new Point(
                            e.Location.X - clickedModule.Location.X,
                            e.Location.Y - clickedModule.Location.Y);
                    }

                    workspacePanel.Invalidate();
                    return;
                }
            }

            // 清除状态
            selectedConnectionPoint = null;
            tempConnection = null;
            hoveredConnection = null;
            workspacePanel.Invalidate();
        }

        private void WorkspacePanel_MouseMove(object sender, MouseEventArgs e)
        {
            // 更新模块悬停状态
            UpdateModuleHoverState(e.Location);

            // 更新连接点悬停状态
            UpdateConnectionPointsHoverState(e.Location);

            // 更新连接线悬停状态
            CheckConnectionHover(e.Location);

            // 拖拽模块
            if (draggingModule != null)
            {
                int newX = e.Location.X - dragOffset.X;
                int newY = e.Location.Y - dragOffset.Y;

                // 网格对齐
                newX = (newX / GRID_SIZE) * GRID_SIZE;
                newY = (newY / GRID_SIZE) * GRID_SIZE;

                // 限制在工作区内
                newX = Math.Max(0, Math.Min(newX, workspacePanel.Width - draggingModule.Size.Width));
                newY = Math.Max(0, Math.Min(newY, workspacePanel.Height - draggingModule.Size.Height));

                draggingModule.Location = new Point(newX, newY);

                // 更新连接点位置
                foreach (var point in draggingModule.ConnectionPoints)
                    point.UpdateLocation();

                // 刷新连接
                UpdateConnectionsForModule(draggingModule);
                workspacePanel.Invalidate();
                return;
            }

            // 拖拽连接线
            if (tempConnection != null && selectedConnectionPoint != null)
            {
                tempConnection.SetCustomEndPoint(e.Location);
                tempConnection.TargetPoint = FindConnectionPointAt(e.Location);
                workspacePanel.Invalidate();
                return;
            }
        }

        private void ModuleLibraryPanel_MouseMove(object sender, MouseEventArgs e)
        {
            UpdateModuleLibraryHoverState();

            // 从模块库拖拽到工作区
            if (draggingModule != null && e.Button == MouseButtons.Left)
            {
                Point mouseInScreen = moduleLibraryPanel.PointToScreen(e.Location);
                Point mouseInWorkspace = workspacePanel.PointToClient(mouseInScreen);

                int newX = mouseInWorkspace.X - dragOffset.X;
                int newY = mouseInWorkspace.Y - dragOffset.Y;

                // 网格对齐
                newX = (newX / GRID_SIZE) * GRID_SIZE;
                newY = (newY / GRID_SIZE) * GRID_SIZE;

                // 当鼠标移出模块库时添加到工作区
                if (e.Location.X > moduleLibraryPanel.Width - 20)
                {
                    if (!modules.Contains(draggingModule))
                        modules.Add(draggingModule);

                    // 限制在工作区内
                    newX = Math.Max(0, Math.Min(newX, workspacePanel.Width - draggingModule.Size.Width));
                    newY = Math.Max(0, Math.Min(newY, workspacePanel.Height - draggingModule.Size.Height));

                    draggingModule.Location = new Point(newX, newY);
                    workspacePanel.Invalidate();
                }
            }
        }

        private void UpdateModuleLibraryHoverState()
        {
            Point mousePos = moduleLibraryPanel.PointToClient(Cursor.Position);
            int? newHoveredIndex = null;

            for (int i = 0; i < modulePrototypes.Count; i++)
            {
                var prototype = modulePrototypes[i];
                Rectangle rect = new Rectangle(
                    prototype.Location.X - 10,
                    prototype.Location.Y - 10,
                    prototype.Size.Width + 20,
                    prototype.Size.Height + 20);

                if (rect.Contains(mousePos))
                {
                    newHoveredIndex = i;
                    break;
                }
            }

            if (newHoveredIndex != hoveredPrototypeIndex)
            {
                hoveredPrototypeIndex = newHoveredIndex;
                moduleLibraryPanel.Invalidate();
            }
        }

        private void ModuleLibraryPanel_MouseLeave(object sender, EventArgs e)
        {
            if (hoveredPrototypeIndex.HasValue)
            {
                hoveredPrototypeIndex = null;
                moduleLibraryPanel.Invalidate();
            }
        }

        private void ModuleLibraryPanel_MouseDown(object sender, MouseEventArgs e)
        {
            // 从模块库选择原型
            Module clickedPrototype = FindPrototypeAt(e.Location);
            if (clickedPrototype != null)
            {
                int relativeX = e.Location.X - clickedPrototype.Location.X;
                int relativeY = e.Location.Y - clickedPrototype.Location.Y;

                // 创建新模块用于拖拽
                draggingModule = new Module(
                    clickedPrototype.Name,
                    clickedPrototype.Type,
                    new Point(0, 0));

                dragOffset = new Point(relativeX, relativeY);
            }
        }

        private void WorkspacePanel_MouseUp(object sender, MouseEventArgs e)
        {
            // 结束拖拽模块
            if (draggingModule != null)
            {
                draggingModule = null;
                return;
            }

            // 完成连接创建
            if (tempConnection != null && selectedConnectionPoint != null)
            {
                ConnectionPoint targetPoint = FindConnectionPointAt(e.Location);
                if (targetPoint != null && targetPoint != selectedConnectionPoint &&
                    targetPoint.Type != selectedConnectionPoint.Type)
                {
                    // 确保方向正确（输出 -> 输入）
                    ConnectionPoint source = selectedConnectionPoint.Type == ConnectionPointType.Output
                        ? selectedConnectionPoint : targetPoint;
                    ConnectionPoint target = selectedConnectionPoint.Type == ConnectionPointType.Output
                        ? targetPoint : selectedConnectionPoint;

                    connections.Add(new Connection(source, target));
                }

                tempConnection = null;
                selectedConnectionPoint = null;
                workspacePanel.Invalidate();
            }
        }

        private void WorkspacePanel_MouseLeave(object sender, EventArgs e)
        {
            // 离开工作区时清除临时状态
            if (tempConnection != null)
            {
                tempConnection = null;
                selectedConnectionPoint = null;
                workspacePanel.Invalidate();
            }

            // 清除悬停状态
            foreach (var module in modules)
                module.IsHovered = false;
            foreach (var point in modules.SelectMany(m => m.ConnectionPoints))
                point.IsHovered = false;
            if (hoveredConnection != null)
            {
                hoveredConnection.IsHovered = false;
                hoveredConnection = null;
            }
        }

        private void ModuleLibraryPanel_MouseUp(object sender, MouseEventArgs e)
        {
            draggingModule = null;
        }

        private void WorkspacePanel_MouseClick(object sender, MouseEventArgs e)
        {
            // 右键点击空白处清除选中状态
            if (e.Button == MouseButtons.Right && FindModuleAt(e.Location) == null)
            {
                foreach (var module in modules)
                    module.IsSelected = false;
                workspacePanel.Invalidate();
            }
        }

        // 辅助方法：查找模块
        private Module FindModuleAt(Point location)
        {
            for (int i = modules.Count - 1; i >= 0; i--)
            {
                var module = modules[i];
                if (new Rectangle(module.Location, module.Size).Contains(location))
                    return module;
            }
            return null;
        }

        // 辅助方法：查找原型
        private Module FindPrototypeAt(Point location)
        {
            foreach (var prototype in modulePrototypes)
            {
                Rectangle rect = new Rectangle(
                    prototype.Location.X - 10,
                    prototype.Location.Y - 10,
                    prototype.Size.Width + 20,
                    prototype.Size.Height + 20);

                if (rect.Contains(location))
                    return prototype;
            }
            return null;
        }

        // 辅助方法：检查是否点击连接点
        private bool IsPointOnConnectionPoint(Point location, Module module)
        {
            foreach (var point in module.ConnectionPoints)
            {
                if (point.ContainsPoint(location))
                    return true;
            }
            return false;
        }

        // 辅助方法：查找连接点
        private ConnectionPoint FindConnectionPointAt(Point location)
        {
            foreach (var module in modules)
            {
                foreach (var point in module.ConnectionPoints)
                {
                    if (point.ContainsPoint(location))
                        return point;
                }
            }
            return null;
        }

        // 辅助方法：更新模块悬停状态
        private void UpdateModuleHoverState(Point location)
        {
            foreach (var module in modules)
            {
                bool isHovered = new Rectangle(module.Location, module.Size).Contains(location) &&
                                !IsPointOnConnectionPoint(location, module) &&
                                draggingModule == null;
                if (module.IsHovered != isHovered)
                {
                    module.IsHovered = isHovered;
                    workspacePanel.Invalidate();
                }
            }
        }

        // 辅助方法：更新连接点悬停状态
        private void UpdateConnectionPointsHoverState(Point location)
        {
            foreach (var point in modules.SelectMany(m => m.ConnectionPoints))
            {
                bool isHovered = point.ContainsPoint(location) && draggingModule == null;
                if (point.IsHovered != isHovered)
                {
                    point.IsHovered = isHovered;
                    workspacePanel.Invalidate();
                }
            }
        }

        // 辅助方法：检查连接线悬停
        private void CheckConnectionHover(Point location)
        {
            Connection newHovered = null;
            foreach (var connection in connections)
            {
                if (connection.IsNearPoint(location))
                {
                    newHovered = connection;
                    break;
                }
            }

            if (newHovered != hoveredConnection)
            {
                if (hoveredConnection != null)
                    hoveredConnection.IsHovered = false;

                hoveredConnection = newHovered;
                if (hoveredConnection != null)
                    hoveredConnection.IsHovered = true;

                workspacePanel.Invalidate();
            }
        }

        // 辅助方法：更新模块相关连接
        private void UpdateConnectionsForModule(Module module)
        {
            foreach (var point in module.ConnectionPoints)
            {
                foreach (var connection in point.Connections)
                {
                    workspacePanel.Invalidate();
                }
            }
        }

        // 辅助方法：删除连接
        private void RemoveConnection(Connection connection)
        {
            if (connection == null) return;

            // 清理连接点引用
            if (connection.SourcePoint != null)
            {
                connection.SourcePoint.Connections.Remove(connection);
                connection.SourcePoint.IsConnected = connection.SourcePoint.Connections.Count > 0;
            }

            if (connection.TargetPoint != null)
            {
                connection.TargetPoint.Connections.Remove(connection);
                connection.TargetPoint.IsConnected = connection.TargetPoint.Connections.Count > 0;
            }

            connections.Remove(connection);
            hoveredConnection = null;
            workspacePanel.Invalidate();
        }

        // 辅助方法：创建圆角矩形路径
        private GraphicsPath CreateRoundedRectanglePath(Rectangle rect, int radius)
        {
            GraphicsPath path = new GraphicsPath();

            if (radius <= 0)
            {
                path.AddRectangle(rect);
                return path;
            }

            int diameter = radius * 2;
            Size size = new Size(diameter, diameter);
            Rectangle arc = new Rectangle(rect.Location, size);

            // 左上角
            path.AddArc(arc, 180, 90);

            // 右上角
            arc.X = rect.Right - diameter;
            path.AddArc(arc, 270, 90);

            // 右下角
            arc.Y = rect.Bottom - diameter;
            path.AddArc(arc, 0, 90);

            // 左下角
            arc.X = rect.Left;
            path.AddArc(arc, 90, 90);

            path.CloseFigure();
            return path;
        }
    }
}